#include<bits/stdc++.h> 
using namespace std;
//	一个乒乓球俱乐部有N张空桌子给大众使用，编号为1~N。对于任何一对玩家，如果他们到达的时
//	候有空桌子，则可以注册最小编号的空桌子给他们用。如果所有的桌子都被占据了，那么就得在
//	队列里等待。每一对玩家最多可以玩2小时。我的工作是计算每一队伍的等待时间，以及每一张
//	桌子那天接受的玩家数。比较棘手的一点是，俱乐部预留了几张桌子给VIP用户，当VIP桌子开着
//	第一对VIP可以优先去使用。如果没有VIP在队列中，则下一对人可以去使用。如果轮到了VIP，
//	即使没有VIP位置，他们也可以像普通玩家一样直接玩。 
//1.每个输入有一个测试用例。对于每一个测试用例，第一行包含了一个正整数N≤10000，表示总共
//	有几对玩家。
//2.紧跟着N行，每行有两个时间和一个VIP标签，时间格式为HH:MM:SS的时间表示到达时间，P表示
//	玩的时间（单位分），VIP标签由1表示VIP，0表示普通人。
//3.紧跟着两个正整数K≤100和M<K，分别表示总桌子数和VIP桌子数。最后一行包含M个VIP桌编号。 
//4.保证每个到达的队伍都是在8点~21点之间。没有两组是一起到达的。
//5.对于每一个测试用例，每一行输出每组到达时间、 开始玩的时间以及等待时间，按照到达时间
//	升序排列。等待时间四舍五入，单位为分。然后在一行中输出每个桌子今天服务了多少人。
//6.如果某个人到关门了还没被服务到，则不需要被打印出来、
//7.队列，逻辑分析，分类讨论 

//这道题跟之前银行的题目很像，但是由于加入了所谓的VIP，就变得复杂不堪，而且题目描述模棱
//两可，测试点很难顶……因为花了太多时间做题，然后大部分流程跟银行那个一样，所以就不多
//介绍一些常规操作了 
struct Player{
	int ID;
	int arrive;
	int start = 76501;
	int spend;
	int vip;
	int table = 0;
	bool operator <(const Player &b) const{
		return arrive<b.arrive;
	}
};
struct Table{
	int vip = 0;
	bool is_ok = true;
	vector<int> history;	//存储该桌子的历史记录 
};
void getTime(int sec){	//秒转化成规定格式输出 
	int hh,mm,ss;
	ss = sec % 60;
	hh = sec / 3600;
	mm = (sec - hh * 3600) / 60;
	printf("%02d:%02d:%02d ",hh,mm,ss);
}
map<int, Player> player_map;
bool cmp(int a, int b){	//输出比较用的函数 
	Player ap = player_map[a];
	Player bp = player_map[b];
	if(ap.start<bp.start)return ap.start < bp.start;
	else if(ap.start == bp.start) return ap.vip>bp.vip;
	else if(ap.start==bp.start && ap.vip==bp.vip) return ap.table<bp.table;
	return false;
}
int main(){
	int N;
	cin>>N;
	set<Player> players; 
	for(int i=0;i<N;i++){
		int hh, mm, ss;
		scanf("%d:%d:%d",&hh,&mm,&ss);
		Player ply;
		ply.ID = i;
		ply.arrive = (hh*3600+mm*60+ss);
		cin>>ply.spend>>ply.vip;
		if(ply.spend>120) ply.spend = 7200;
		else ply.spend = ply.spend * 60;
		players.insert(ply);
	}
	int K, M;
	cin>>K>>M;
	Table tables[K+1];
	set<int> vip_tables;	//用来存储并直接排序 
	for(int i=0;i<M;i++){
		int t;
		cin>>t;
		tables[t].vip = 1;
		vip_tables.insert(t);
	}
	if(N==0){
		for(int i = 0;i<K;i++){
			cout<<0;
			if(i==K-1) cout<<endl;
			else cout<<" ";
		}
		return 0;
	}
	set<Player>::iterator it;
	vector<int> all_players;
	for(it = players.begin();it!=players.end();it++){
		all_players.push_back(it->ID);
		player_map[it->ID] = (*it);
	}
	int time = player_map[all_players.front()].arrive-1;
	while(!all_players.empty()&&time<75600){
		Player ply = player_map[all_players.front()];
		time++;
		for(int i = 1;i<K+1;i++){	//因为vip桌子的存在，我不得不先全部遍历排查有没有结束的，再去遍历排查用户合适的 
			if(all_players.empty()) break;
			if(tables[i].is_ok==false){
				Player occupy = player_map[tables[i].history.back()];
				if(occupy.start+occupy.spend==time){
					tables[i].is_ok=true;
					if(tables[i].vip==1) vip_tables.insert(i);
				}
			}
		}
		for(int i =1;i<K+1;i++){	//多种情况分析，应该看英文挺容易看懂的 
			if(tables[i].is_ok==true){
				if(ply.arrive>time) continue;
				if(ply.vip==1){
					if(vip_tables.empty()){
						tables[i].is_ok = false;
						tables[i].history.push_back(ply.ID);
						ply.table = i;
					}
					else{
						tables[(*vip_tables.begin())].is_ok = false;
						tables[(*vip_tables.begin())].history.push_back(ply.ID);
						ply.table = (*vip_tables.begin());
						vip_tables.erase(vip_tables.begin());
					}
					ply.start = time;
					all_players.erase(all_players.begin());
					player_map[ply.ID] = ply;
					if(all_players.empty()) break;
					else ply = player_map[all_players.front()];
				}
				else{
					if(tables[i].vip==false){
						tables[i].is_ok = false;
						tables[i].history.push_back(ply.ID);
						ply.table = i;
						ply.start = time;
						all_players.erase(all_players.begin());
						player_map[ply.ID] = ply;
						if(all_players.empty()) break;
						else ply = player_map[all_players.front()];
					}
					else{
						vector<int>::iterator it;
						bool f = false;
						for(it = all_players.begin();it!=all_players.end();it++){
							if(player_map[(*it)].arrive<=time && player_map[(*it)].vip==1)
							{
								f = true;
								break;
							 } 
						}
						tables[i].is_ok = false;
						if(f==true){
							ply = player_map[(*it)];
							tables[i].history.push_back(ply.ID);
							ply.start = time;
							ply.table = i;
							all_players.erase(it);
							
						}else{
							tables[i].history.push_back(ply.ID);
							ply.table = i;
							ply.start = time;
							all_players.erase(all_players.begin());
						}
						player_map[ply.ID] = ply;
						set<int>::iterator itt;
						for(itt=vip_tables.begin();itt!=vip_tables.end();itt++){
							if((*itt) == i){
								vip_tables.erase(itt);
								break;
							}
						}
						if(all_players.empty()) break;
						else ply = player_map[all_players.front()];
					}
			}
				
			}
		}
	}
	int counts[K+1];
	fill(counts+1,counts+K+1,0);
	vector<int> can_players;
	for(it = players.begin();it!=players.end();it++){
		int id = it->ID;
		Player ply = player_map[id];
		if(ply.start<75600){
			can_players.push_back(ply.ID);
			counts[ply.table]++;
		}
	}
	sort(can_players.begin(),can_players.end(),cmp);
	for(unsigned int i =0;i<can_players.size();i++){
		Player ply = player_map[can_players[i]];
		getTime(ply.arrive);
		getTime(ply.start);
		int cha = round((ply.start - ply.arrive) / 60.0);
		cout<<cha<<endl;
	}
	for(int i = 1;i<K+1;i++){
		cout<<counts[i];
		if(i == K) cout<<endl;
		else cout<<" ";
	}
	return 0;
} 
 